package com.anche.cywebnew.aop;

import com.alibaba.fastjson.JSON;
import com.anche.cywebnew.Pojo.systemManager.SysUser;
import com.anche.cywebnew.Service.logManager.LogService;
import com.anche.cywebnew.Utils.Thread.ThreadPoolUtil;
import com.anche.cywebnew.Utils.annotation.OptLog;
import com.fasterxml.jackson.annotation.JsonAlias;
import org.apache.shiro.SecurityUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * @program: cywebnew
 * @description:
 * @author: LCHQ
 * @create: 2021-04-15 14:43
 */
@Aspect
@Order(1)
public class OptLogAop {

    @Autowired
    private LogService logService;

    @Autowired
    private HttpServletRequest request;

    /**
     * 日志切入点
     */
    @Pointcut("@annotation(com.anche.cywebnew.Utils.annotation.OptLog)")
    private void getLogPointCut() {
    }

    /**
     * 操作成功返回结果记录日志
     * @param joinPoint
     * @param result
     */
    @AfterReturning(pointcut = "getLogPointCut()", returning = "result")
    public void doAfterReturning(JoinPoint joinPoint, Object result) {
        try {
            MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
            Method method = methodSignature.getMethod();
            OptLog optLog = method.getAnnotation(OptLog.class);
            SysUser sysUser = (SysUser) SecurityUtils.getSubject().getPrincipal();
            String ip = getRemoteHost(request);   // 获取终端ip地址

            //异步记录日志
            ThreadPoolUtil.execute(new Runnable() {
                @Override
                public void run() {
                    logService.insertLogInfo(optLog.title() + "成功, 操作返回信息：" + JSON.toJSONString(result), optLog.type().ordinal() + "", "1", sysUser.getId(), sysUser.getName(), sysUser.getOrgan(), ip);
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 操作发生异常记录日志
     * @param joinPoint
     * @param exception
     */
    @AfterThrowing(pointcut = "getLogPointCut()", throwing = "exception")
    public void doAfterThrowing(JoinPoint joinPoint, Exception exception) {
        try {
            MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
            Method method = methodSignature.getMethod();
            OptLog optLog = method.getAnnotation(OptLog.class);
            SysUser sysUser = (SysUser) SecurityUtils.getSubject().getPrincipal();
            String ip = getRemoteHost(request);   // 获取终端ip地址

            //异步记录日志
            ThreadPoolUtil.execute(new Runnable() {
                @Override
                public void run() {
                    logService.insertLogInfo(optLog.title() + "失败，错误信息：" + exception.getMessage(), optLog.type().ordinal() + "", "0", sysUser.getId(), sysUser.getName(), sysUser.getOrgan(), ip);
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private String getRemoteHost(javax.servlet.http.HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip;
    }
}
